package com.md.application;

import com.md.infrastructure.config.AzureSamlConfig;
import com.md.infrastructure.configuration.AzureSamlCoreConfiguration;
import com.md.infrastructure.util.SamlUtil;
import com.md.model.system.CommonResult;
import org.opensaml.saml.saml2.core.AuthnRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;

/**
 * @author 刘骄阳
 * 2024-03-24 1:20
 */
@Service
public class LoginApplicationService implements LoginApi {
  static byte[] samlDeflate(final String s) {
    try {
      ByteArrayOutputStream b = new ByteArrayOutputStream();
      DeflaterOutputStream deflater = new DeflaterOutputStream(b, new Deflater(Deflater.DEFLATED, true));
      deflater.write(s.getBytes(StandardCharsets.UTF_8));
      deflater.finish();
      return b.toByteArray();
    } catch (IOException ex) {
      throw ServerException.build(ErrorEnum.DECODING_ERROR, ex);
    }
  }

  // 客户端公钥加密,服务端私钥解密,服务端使用客户端的公钥加密,客户端使用私钥解密
  @Override
  public CommonResult<AzureSamlLoginResponse> azureSaml(final AzureSamlLoginRequest request) {

//    List<AzureSamlConfig> analysis = AzureSamlCoreConfiguration.analysis("https://login.microsoftonline.com/00618cc4-0e79-43ef-9df6-41ddc9a38d62/federationmetadata/2007-06/federationmetadata.xml?appid=a2c39ba2-3cc0-4a44-acaa-20b96dc35ebd");
    List<AzureSamlConfig> analysis = AzureSamlCoreConfiguration.analysis("RDIC-DEV.xml");
    AzureSamlConfig azureSamlConfig = analysis.get(0);
    AuthnRequest authnRequest = SamlUtil.createRequest(azureSamlConfig);
    authnRequest.setAssertionConsumerServiceURL("http://localhost:8090/saml/callback/");
//    authnRequest.setAssertionConsumerServiceURL("https://3s35r49356.oicp.vip/users/response");

    String s = Base64.getEncoder().encodeToString(samlDeflate(SamlUtil.serialize(authnRequest)));
    UriComponentsBuilder uriBuilder = UriComponentsBuilder
      .fromUriString(azureSamlConfig.getSignOnServiceBinding().getUrl());
    addParameter("SAMLRequest", s, uriBuilder);
    // 此处应记录一个登录记录,用于回调的时候拿到对应的请求信息
    addParameter("RelayState", "NOUST123", uriBuilder);
    addParameter("SigAlg", null, uriBuilder);
    addParameter("Signature", null, uriBuilder);
    return CommonResult.success(AzureSamlLoginResponse.builder().url(uriBuilder.build(true).toUriString()).build());
  }

  private void addParameter(final String name, final String value, final UriComponentsBuilder builder) {
    Assert.hasText(name, "name cannot be empty or null");
    if (StringUtils.hasText(value)) {
      builder.queryParam(UriUtils.encode(name, StandardCharsets.ISO_8859_1),
        UriUtils.encode(value, StandardCharsets.ISO_8859_1));
    }
  }
}
